package gossip.v1;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class ProductionGossipNode {
    private static final int GOSSIP_INTERVAL = 500;
    private static final int FAILURE_DETECTION_INTERVAL = 1000;
    private static final long SUSPECT_THRESHOLD = 3000;
    private static final int INDIRECT_CHECK_COUNT = 2;
    private static final int MAX_GOSSIP_TARGETS = 3;
    private static final int MAX_SESSION_QUEUE = 1000;

    private final int port;
    private final GossipCore gossipCore;
    private final GossipTransport transport;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);

    public ProductionGossipNode(int port) {
        this.port = port;
        this.gossipCore = new GossipCore(port);
        this.transport = new GossipTransport(port, gossipCore);
        this.gossipCore.setTransport(transport);
    }

    public void start() {
        transport.start();
        gossipCore.start(scheduler);
        System.out.printf("[GOSSIP] Node started on port %d. ID: %s%n", port, gossipCore.getLocalNodeId());
    }

    public void joinCluster(InetSocketAddress seedNode) {
        gossipCore.join(seedNode);
    }

    public void updateMetadata(String key, String value) {
        gossipCore.updateLocalMetadata(key, value);
    }

    public Map<String, MemberState> getClusterMembers() {
        return gossipCore.getMembershipTable().getMembers();
    }

    public static void main(String[] args) {
        int port = args.length > 0 ? Integer.parseInt(args[0]) : 9000;
        ProductionGossipNode node = new ProductionGossipNode(port);
        node.start();

        if (args.length > 1) {
            String[] seedParts = args[1].split(":");
            node.joinCluster(new InetSocketAddress(seedParts[0], Integer.parseInt(seedParts[1])));
        }
    }
}
